#pragma once
#include <filesystem>
#include <string>
#include <memory>
#include <vector>

#include <SDL2/SDL.h>


struct GLTexture {
	int width;
	int height;
	SDL_Texture* texture;

	GLTexture(int width, int height, SDL_Texture* texture)
		:width(width), height(height), texture(texture)
	{
	}

	~GLTexture()
	{
		if (texture) {
			SDL_DestroyTexture(texture);
			texture = nullptr;
			width = -1;
			height = -1;
		}
	}
};

struct ResourceData {
	bool bloaded = false;
	std::string name;
	int size;
	std::vector<std::shared_ptr<GLTexture>> resources;

	//重载[]操作符
	std::shared_ptr<GLTexture> operator[](size_t index) {
		if (index < 0 || index >= resources.size()) {
			SDL_LogError(SDL_LOG_CATEGORY_ERROR, "index: %zu out of range, max: %ld", index, resources.size());
		}
		return resources[index];
	}
};

enum EquipType {
	EquipType_Weapon = 1,
	EquipType_Cloth = 2,
};

enum ActorType {
	ActrorType_None = 0,
	ActorType_GroundItem = 1,			//地面物体 门 隐形路径 隐形墙 门卫 上下楼梯 炼丹炉 云雾
	ActorType_PropertyItem = 2,			//属性物品 火眼金睛 玄明石 金刚丹
	ActorType_Equip = 4,				//武器
	ActorType_Monster = 8,				//怪物
	ActorType_BusinessMan = 16,			//商人
	ActorType_NPC = 32,					//NPC
};

//actor数据结构，后续可能会继续扩展
struct ActorInfo {
	ActorType actorType;				//对象类型
	const char* name;					//名称
	int spriteFrameWidth;				//帧宽度
	int spriteFrameHeight;				//帧高度
	int animSequenceIndex;				//动画序列帧下标
	const char* resourceName;			//资源名  group_index
	//怪物属性
	int baseHp = -1;					//基础血量/武器优先级
	int baseAttack = -1;				//基础攻击/武器攻击力
	int baseDef = -1;					//基础防御/防具防御力
	union {
		int useCount = -1;				//最大使用数量/武器是-2，防具是-3
		int moneyEarn;					//金币获得
	};
	const char* itemDescrib = "";			//描述文本

	//只有实例化之后才初始化碰撞		69 杨戬 96 32	67 哮天犬 32 32		72 牛魔王 32 45  其它的如果有图则使用帧宽度和帧高度 没有默认32 32
	//int width;				//碰撞宽度
	//int height;				//碰撞高度
	int currFrameIdx = 0;				//当前下标

	static std::vector<std::vector<int>> objectAnimSequenceArray;

	std::shared_ptr<GLTexture> getRenderResource();

	int getAnimFrameSize();
	/**
	 * @brief 获取当前的序列帧下标
	 * @author Alex.peng
	 */
	int getAnimIndex();
};

class ResourceMgr {
private:
	static ResourceMgr m_instance;
	std::vector<ResourceData> m_datas;
	std::vector<ActorInfo> m_actors;
	SDL_Renderer* m_renderer = nullptr;

	std::vector<std::shared_ptr<class actor>> m_actorObjs;

private:
	ResourceMgr() = default;
public:
	static ResourceMgr& get();
	bool init(SDL_Renderer* pRenderer, const std::filesystem::path& basePath, const std::filesystem::path& dataPath);
	bool loadResourceImages(SDL_Renderer* pRenderer, const std::filesystem::path& basePath, const std::string& filename, int count, std::vector<std::shared_ptr<GLTexture>>& imageDatas);
	ActorInfo& getActor(int index);


public:
	ResourceData& operator[](int index);
	ResourceData& operator[](const std::string& name);

private:
	short readBinaryShort(std::ifstream& fs);
	bool load_resources_config(const std::filesystem::path& config_file_path);
	bool load_actors_config(const std::filesystem::path& config_file_path);
};